package com.dogstudio.popstart.view;

import android.content.Context;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;

import com.dogstudio.popstart.config.Config;
import com.dogstudio.popstart.utils.LogUtils;

import java.util.ArrayList;


public class GamePanel extends ViewGroup {
    private StartView[][] mGroup;
    private int block;
    private boolean isSelected = false;
    private ArrayList<StartView> selectedArea;
    private StartView mCurrentView;
    private OnScoreListener mListener;

    public GamePanel(Context context) {
        super(context);
        init();
    }

    public GamePanel(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        block = Config.SCREEN_WIDTH / Config.SIZE;
        selectedArea = new ArrayList<StartView>();
    }

    public void setOnScoreListener(OnScoreListener l) {
        mListener = l;
    }

    public void startGame() {
        mGroup = new StartView[Config.SIZE][Config.SIZE];
        for (int i = 0; i < Config.SIZE; i++) {
            for (int j = 0; j < Config.SIZE; j++) {
                mGroup[i][j] = new StartView(getContext());
                addView(mGroup[i][j]);
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mGroup != null) {
            for (int i = 0; i < Config.SIZE; i++) {
                for (int j = 0; j < Config.SIZE; j++) {
                    if (mGroup[i][j] != null) {
                        mGroup[i][j].measure(widthMeasureSpec, heightMeasureSpec);
                    }
                }
            }
        }
        setMeasuredDimension(Config.SCREEN_WIDTH, Config.SCREEN_WIDTH);
    }

    @Override
    protected void onLayout(boolean isChange, int left, int top, int right, int bottom) {
        if (mGroup != null) {
            int mLeft = 0;
            for (int j = 0; j < Config.SIZE; j++) {
                int mTop = Config.SCREEN_WIDTH - block;
                for (int i = Config.SIZE - 1; i >= 0; i--) {
                    if (mGroup[i][j] != null) {
                        mGroup[i][j].setPosition(new Point(i, j));
                        mGroup[i][j].layout(mLeft, mTop, mLeft + block, mTop + block);
                        mTop -= block;
                    }
                }
                mLeft += block;
            }
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (isSelected && mCurrentView == calInStartRenge(x, y)) {
                    mergeGroup();
                } else {
                    isSelected = false;
                    cancelSelectedItems();
                    mCurrentView = calInStartRenge(x, y);
                    if (mCurrentView != null) {
                        getAreaStart(mCurrentView);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }

    private void cancelSelectedItems() {
        if (selectedArea.size() > 0) {
            for (StartView item : selectedArea) {
                item.setSelectState(false);
            }
            selectedArea.clear();
        }
    }

    private boolean isValiadNum(int num) {
        return num >= 0 && num < Config.SIZE;
    }

    /**
     * 计算触摸区域所在的StartView
     */
    private StartView calInStartRenge(float x, float y) {
        int j = (int) (x / block);
        int i = (int) (y / block);
        if (isValiadNum(i) && isValiadNum(j)) {
            return mGroup[i][j];
        } else {
            return null;
        }
    }

    /**
     * 计算出触摸区域关联的星星，如果个数大于两个则显示选中状态，否则没有
     */
    private void getAreaStart(StartView view) {
        addSelectedItem(view);
        if (selectedArea.size() > 1) {
            for (StartView item : selectedArea) {
                item.setSelectState(true);
            }
            isSelected = true;
        }
    }

    private void addSelectedItem(StartView view) {
        if (selectedArea.contains(view)) {
            return;
        }
        selectedArea.add(view);
        Point p = view.getPosition();
        int type = view.getType();
        int i = p.x;
        int j = p.y;
        LogUtils.e("addSelectedItem:i=" + i + ", j=" + j);
        // 获取在左边的item
        getSide(i, j - 1, type);
        // 获取在上边的item
        getSide(i - 1, j, type);
        // 获取在右边的item
        getSide(i, j + 1, type);
        // 获取在下边的item
        getSide(i + 1, j, type);
    }

    private void getSide(int i, int j, int type) {
        if (isValiadNum(i) && isValiadNum(j) && mGroup[i][j] != null && mGroup[i][j].getType() == type) {
            addSelectedItem(mGroup[i][j]);
        }
    }


    /**
     * 消除星星，合并星星，向左向、下移动
     */
    private void mergeGroup() {
        isSelected = false;
        //消除星星
        if (mListener != null) {
            mListener.onScore(selectedArea.size());
        }
        for (StartView item : selectedArea) {
            Point p = item.getPosition();
            removeView(mGroup[p.x][p.y]);
            mGroup[p.x][p.y] = null;
        }
        // 执行合并操作 向下合并
        ArrayList<Integer> list = new ArrayList<Integer>();
        for (int j = 0; j < Config.SIZE; j++) {
            int size = Config.SIZE;
            for (int i = 0; i < Config.SIZE; i++) {
                if (mGroup[i][j] == null) {
                    size--;
                    for (int z = i; z > 0; z--) {
                        mGroup[z][j] = mGroup[z - 1][j];
                        mGroup[z - 1][j] = null;
                    }
                }
            }
            if (size == 0) {
                list.add(j);
            }
        }
        // 执行合并操作 向左合并
        if (list.size() > 0) {
            for (int j = Config.SIZE; j > 0; j--) {
                if (list.contains(j)) {
                    for (int i = 0; i < Config.SIZE; i++) {
                        for (int z = j; z < Config.SIZE - 1; z++) {
                            mGroup[i][z] = mGroup[i][z + 1];
                            mGroup[i][z + 1] = null;
                        }
                    }
                }
            }
        }
        requestLayout();
    }

    public interface OnScoreListener {
        void onScore(int size);

        void onSuccess();

        void onFailure();
    }

}
